package chapter3.lessons.copyPart;

import java.io.*;

/**
 * @Project ：learn_java
 * @File ：RecursivelyCopyAllFiles.java
 * @IDE ：IntelliJ IDEA
 * @Author ：自由如风间
 * @Date ：2025/3/1 10:05
 * @Description ：grok写的，递归复制所有文件的程序
 */

public class RecursivelyCopyAllFiles {
    public static void main(String[] args) {
        // 定义源文件夹和目标文件夹路径
        File sourceFolder = new File("D:/source");
        File destFolder = new File("D:/destination");

        try {
            copyFolder(sourceFolder, destFolder);
            System.out.println("文件夹及其所有文件复制成功！");
        } catch (IOException e) {
            System.err.println("复制文件夹时出错：" + e.getMessage());
        }
    }

    /**
     * 递归复制文件夹及其所有文件
     *
     * @param source 源文件夹
     * @param dest   目标文件夹
     * @throws IOException 如果发生 I/O 错误
     */
    public static void copyFolder(File source, File dest) throws IOException {
        // 检查源路径是否有效
        if (!source.exists()) {
            throw new IllegalArgumentException("源路径不存在");
        }

        // 如果源是文件，直接复制
        if (source.isFile()) {
            copyFile(source, dest);
            return;
        }

        // 如果源是文件夹，创建目标文件夹
        if (!dest.exists()) {
            dest.mkdirs(); // 创建目录及其父目录
        }

        // 获取源文件夹中的所有文件和子文件夹
        File[] files = source.listFiles();
        if (files == null) {
            return; // 如果为空，直接返回
        }

        // 遍历并复制每个文件或子文件夹
        for (File file : files) {
            File destFile = new File(dest, file.getName());
            if (file.isDirectory()) {
                // 递归复制子文件夹
                copyFolder(file, destFile);
            } else {
                // 复制文件
                copyFile(file, destFile);
            }
        }
    }

    /**
     * 复制单个文件
     *
     * @param source 源文件
     * @param dest   目标文件
     * @throws IOException 如果发生 I/O 错误
     */
    public static void copyFile(File source, File dest) throws IOException {
        try (BufferedInputStream bis = new BufferedInputStream(new FileInputStream(source));
             BufferedOutputStream bos = new BufferedOutputStream(new FileOutputStream(dest))) {
            byte[] buffer = new byte[8192]; // 8KB 缓冲区
            int bytesRead;
            while ((bytesRead = bis.read(buffer)) != -1) {
                bos.write(buffer, 0, bytesRead);
            }
        }
    }

}
